import re

from .find import find_element
from utils.selenium.highlighted import ElementHighlighted
from utils.selenium.perform import WPerform


class CheckPointMultipleType:
    """
    检查点多个时候的类型
    """
    matching_and = 1  # 全部匹配
    at_least_one = 2  # 至少一个匹配
    all_dont_match = 3 # 全部都不匹配


class CheckPointType:
    equal = 1
    include = 2
    startwith = 3
    endwith = 4
    regular = 5
    equal_no = 6
    include_no = 7
    startwith_no = 8
    endwith_no = 9
    regular_no = 10


# 检查点方法
check_point_type_funcs = {
    CheckPointType.equal: lambda key, text: key == text,
    CheckPointType.equal_no: lambda key, text: key != text,
    CheckPointType.include: lambda key, text: key in text,
    CheckPointType.include_no: lambda key, text: key not in text,
    CheckPointType.startwith: lambda key, text: text.startswith(key),
    CheckPointType.startwith_no: lambda key, text: not text.startswith(key),
    CheckPointType.endwith: lambda key, text: text.endswith(key),
    CheckPointType.endwith_no: lambda key, text: not text.endswith(key),
    CheckPointType.regular: lambda key, text: re.compile(key).match(text) is not None,
    CheckPointType.regular_no: lambda key, text: re.compile(key).match(text) is None,
}


def check_point_fill(item: dict, value: str):
    """校验失败"""
    checkpoint_type_name = item.get('checkpoint_type_name')
    checkpoint_key = item.get('checkpoint_key')
    find_type_name = item.get('find_type_name')
    find_key = item.get('find_key')
    find_multiple = item.get('find_multiple')
    check_point_multiple_type_name = item.get('check_point_multiple_type_name')
    mutable_str = ""
    if find_multiple:
        mutable_str = "多检查类型: 【%s】" % check_point_multiple_type_name
    err_str = '检查点错误 ==> 校验类型【%s】, 校验字段【%s】, 查找类型【%s】, 查找参数【%s】, 查找到的值【%s】, %s' % (checkpoint_type_name, checkpoint_key, find_type_name, find_key, value, mutable_str)
    raise Exception(err_str)


def run_check_point(perform: WPerform, item: dict, other_query: dict):
    """
    执行检查点
    :param perform:
    :param item: 用例数据
    :param other_query: 顶层带过来的额外参数
    :return:
    """
    checkpoint_type = item.get('checkpoint_type')
    checkpoint_key = item.get('checkpoint_key')
    find_multiple = item.get('find_multiple')
    check_point_multiple_type = item.get('check_point_multiple_type')
    find_data = find_element(perform, item)
    # 获取检查点方法
    check_point_func = check_point_type_funcs.get(checkpoint_type)

    if find_multiple:
        ElementHighlighted.highlighted(perform, find_data)
        if check_point_multiple_type == CheckPointMultipleType.matching_and:
            for element in find_data:
                text: str = element.text
                if not check_point_func(checkpoint_key, text):
                    check_point_fill(item, text)
        elif check_point_multiple_type == CheckPointMultipleType.all_dont_match:
            for element in find_data:
                text: str = element.text
                if check_point_func(checkpoint_key, text):
                    check_point_fill(item, text)
        elif check_point_multiple_type == CheckPointMultipleType.at_least_one:
            for element in find_data:
                text: str = element.text
                if check_point_func(checkpoint_key, text):
                    return
            check_point_fill(item, text)
    else:
        text: str = find_data.text
        if not check_point_func(checkpoint_key, text):
            check_point_fill(item, text)